﻿#include "MaterialElasticWidget.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMaterialElastic.h"
#include "ui_MaterialElasticWidget.h"
#include <QCloseEvent>
#include <QMessageBox>
#include <QTableWidget>
#include <QTableWidgetItem>
#include <QVariant>

namespace GUI
{
    MaterialElasticWidget::MaterialElasticWidget(EventOper::ParaWidgetInterfaceOperator * oper,Interface::FITKAbaMaterialElastic* item, QWidget* parent) :
        _elasticItem(item), MaterialWidgetBase(oper,parent), _ui(new Ui::MaterialElasticWidget)
    {
        if (_elasticItem == nullptr)return;
        _ui->setupUi(this);

        initTable();
        showValue();
    }

    MaterialElasticWidget::~MaterialElasticWidget()
    {
        delete _ui;
    }

    void MaterialElasticWidget::showValue()
    {
        if (_elasticItem == nullptr)return;
        
        for (int i = 0; i < _ui->comboBoxState->count(); i++){
            if (_ui->comboBoxState->itemData(i) == (int)_elasticItem->getMaterialElasticType()){
                _ui->comboBoxState->setCurrentIndex(i);
                break;
            }
        }

        //设置温度参数显示状态
        if (_elasticItem->getUseTemperatureDependentData()) _ui->checkBox_temp->setCheckState(Qt::CheckState::Checked);
        else _ui->checkBox_temp->setCheckState(Qt::CheckState::Unchecked);

        //显示数据
        showValue(_elasticItem->getMaterialElasticType());
    }

    bool MaterialElasticWidget::checkValue()
    {
        auto checkValue = [=](QString str, int row, int column)->bool {
            //判断数据是否有效
            bool isOk = false;
            str.toDouble(&isOk);
            if (isOk == true)return true;

            QString message = QString(tr("Tabular data for at least one option or suboption\n has either blank or zero valued row(s).\n"));
            message = message + QString(tr("Error: Elastic row: %1\n").arg(row + 1));
            message = message + QString(tr("Error: Elastic column: %1\n").arg(column + 1));
            QMessageBox::warning(this, tr("StructualApp"), message);
            return false;
        };

        int typeIndex = _ui->comboBoxState->currentIndex();
        bool isTemp = _ui->checkBox_temp->isChecked();
        switch (typeIndex) {
        case 0: {
            //强制失去焦点，否则获取数据有错误
            _ui->tableWidget_isotropic->setEnabled(false);
            _ui->tableWidget_isotropic->setEnabled(true);
            int rowNum = _ui->tableWidget_isotropic->rowCount();
            int colNum = _ui->tableWidget_isotropic->columnCount();
            for (int i = 0; i < rowNum; i++) {
                for (int j = 0; j < colNum; j++) {
                    QString value = "";
                    QTableWidgetItem* item = _ui->tableWidget_isotropic->item(i, j);
                    if (item == nullptr)continue;
                    value = item->text();

                    if (j == 2 && isTemp == false) {
                        continue;
                    }
                    else {
                        if (!checkValue(value, i, j))return false;
                    }
                }
            }
            break;
        }
        case 1: {
            //强制失去焦点，否则获取数据有错误
            _ui->tableWidget_EC->setEnabled(false);
            _ui->tableWidget_EC->setEnabled(true);
            int rowNum = _ui->tableWidget_EC->rowCount();
            int colNum = _ui->tableWidget_EC->columnCount();
            for (int i = 0; i < rowNum; i++) {
                for (int j = 0; j < colNum; j++){
                    QString value = "";
                    QTableWidgetItem* item = _ui->tableWidget_EC->item(i, j);
                    if (item == nullptr)continue;
                    value = item->text();

                    if (isTemp == false && j == 9) {
                        continue;
                    }
                    else {
                        if (!checkValue(value, i, j))return false;
                    }
                }
            }
        }
        case 2:{
            //强制失去焦点，否则获取数据有错误
            _ui->tableWidget_Lamina->setEnabled(false);
            _ui->tableWidget_Lamina->setEnabled(true);
            int rowNum = _ui->tableWidget_Lamina->rowCount();
            int colNum = _ui->tableWidget_Lamina->columnCount();
            for (int i = 0; i < rowNum; i++) {
                for (int j = 0; j < colNum; j++) {
                    QString value = "";
                    QTableWidgetItem* item = _ui->tableWidget_Lamina->item(i, j);
                    if (item == nullptr)continue;
                    value = item->text();

                    if (isTemp == false && j == 6) {
                        continue;
                    }
                    else {
                        if (!checkValue(value, i, j))return false;
                    }
                }
            }
        }
        }
        
        return true;
    }

    bool MaterialElasticWidget::saveValue()
    {
        if (_elasticItem == false)return false;

        //设置弹性材料类型
        int  index = _ui->comboBoxState->currentIndex();
        auto state = (Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialElasticType)_ui->comboBoxState->itemData(index).value< int >();
        _elasticItem->setMaterialElasticType(state);

        //设置是否启用温度参数
        bool isTemp = false;
        if (_ui->checkBox_temp->checkState() == Qt::CheckState::Checked) isTemp = true;
        else isTemp = false;
        _elasticItem->setUseTemperatureDependentData(isTemp);
        
        //数据存储
        saveValue(state);
       
        return true;
    }

    void MaterialElasticWidget::on_comboBoxState_activated(int index)
    {
        auto type = (Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialElasticType)_ui->comboBoxState->itemData(index).value< int >();
        changeMaterialElasticType(type);

        //温度参数选择
        bool isTemp = false;
        if (_ui->checkBox_temp->checkState() == Qt::CheckState::Checked) isTemp = true;
        else isTemp = false;
        on_checkBox_temp_clicked(isTemp);
    }

    void GUI::MaterialElasticWidget::on_checkBox_temp_clicked(bool checked)
    {
        int typeIndex = _ui->comboBoxState->currentIndex();
        auto type = (Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialElasticType)_ui->comboBoxState->itemData(typeIndex).value< int >();
        changeMaterialTemp(type, checked);
    }

    void MaterialElasticWidget::initTable()
    {
        if (_elasticItem == nullptr)return;

        //初始化材料类型选择
        _ui->comboBoxState->addItem(tr("Isotropic"), (int)Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialElasticType::IsoTropic);
        _ui->comboBoxState->addItem(tr("EngineeringConstants"), (int)Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialElasticType::EngineeringConstants);
        _ui->comboBoxState->addItem(tr("Lamina"), (int)Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialElasticType::Lamina);
        //_ui->comboBoxState->addItem(tr("Orthotropics"), (int)Interface::FITKAbaMaterialElasticType::Orthotropics);
        //_ui->comboBoxState->addItem(tr("AnIsotopic"), (int)Interface::FITKAbaMaterialElasticType::AnIsotopic);
        //_ui->comboBoxState->addItem(tr("Traction"), (int)Interface::FITKAbaMaterialElasticType::Traction);
        //_ui->comboBoxState->addItem(tr("CoupledTraction"), (int)Interface::FITKAbaMaterialElasticType::CoupledTraction);
        //_ui->comboBoxState->addItem(tr("Shear"), (int)Interface::FITKAbaMaterialElasticType::Shear);

        _ui->tableWidget_isotropic->addTableRowAndItem(0);
        //设置为单行模式
        _ui->tableWidget_isotropic->setIsAloneRow(true);

        _ui->tableWidget_EC->addTableRowAndItem(0);
        //设置为单行模式
        _ui->tableWidget_EC->setIsAloneRow(true);

        _ui->tableWidget_Lamina->addTableRowAndItem(0);
        //设置为单行模式
        _ui->tableWidget_Lamina->setIsAloneRow(true);

        //初始化弹性材料类型
        changeMaterialElasticType(_elasticItem->getMaterialElasticType());
        //初始温度状态
        changeMaterialTemp(_elasticItem->getMaterialElasticType(), _elasticItem->getUseTemperatureDependentData());
    }

    void MaterialElasticWidget::showValue(Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialElasticType type)
    {
        switch (type)
        {
            //材料各项同性参数设置
        case Interface::FITKAbaMaterialBehaviorEnum::IsoTropic:
        {
            int rowNum = _elasticItem->getIsotropicNumberOfRows();
            for (int i = 0; i < rowNum; i++) {
                QTableWidgetItem* item0 = new QTableWidgetItem(QString::number(_elasticItem->getIsotropicYoungsModulus(i)));
                QTableWidgetItem* item1 = new QTableWidgetItem(QString::number(_elasticItem->getIsotropicPoisssonRatio(i)));
                QTableWidgetItem* item2 = new QTableWidgetItem(QString::number(_elasticItem->getIsotropicTemperature(i)));
                _ui->tableWidget_isotropic->setItem(i, 0, item0);
                _ui->tableWidget_isotropic->setItem(i, 1, item1);
                _ui->tableWidget_isotropic->setItem(i, 2, item2);
            }
            break;
        }
        case Interface::FITKAbaMaterialBehaviorEnum::EngineeringConstants:
        {
            int rowNum = _elasticItem->getEngineeringConstantsNumberOfRows();
            for (int i = 0; i < rowNum; i++) {
                QTableWidgetItem* item = new QTableWidgetItem(QString::number(_elasticItem->getEngineeringConstantsE1(i)));
                _ui->tableWidget_EC->setItem(i, 0, item);
                item = new QTableWidgetItem(QString::number(_elasticItem->getEngineeringConstantsE2(i)));
                _ui->tableWidget_EC->setItem(i, 1, item);
                item = new QTableWidgetItem(QString::number(_elasticItem->getEngineeringConstantsE3(i)));
                _ui->tableWidget_EC->setItem(i, 2, item);
                item = new QTableWidgetItem(QString::number(_elasticItem->getEngineeringConstantsNu12(i)));
                _ui->tableWidget_EC->setItem(i, 3, item);
                item = new QTableWidgetItem(QString::number(_elasticItem->getEngineeringConstantsNu13(i)));
                _ui->tableWidget_EC->setItem(i, 4, item);
                item = new QTableWidgetItem(QString::number(_elasticItem->getEngineeringConstantsNu23(i)));
                _ui->tableWidget_EC->setItem(i, 5, item);
                item = new QTableWidgetItem(QString::number(_elasticItem->getEngineeringConstantsG12(i)));
                _ui->tableWidget_EC->setItem(i, 6, item);
                item = new QTableWidgetItem(QString::number(_elasticItem->getEngineeringConstantsG13(i)));
                _ui->tableWidget_EC->setItem(i, 7, item);
                item = new QTableWidgetItem(QString::number(_elasticItem->getEngineeringConstantsG23(i)));
                _ui->tableWidget_EC->setItem(i, 8, item);
                item = new QTableWidgetItem(QString::number(_elasticItem->getEngineeringConstantsTemperature(i)));
                _ui->tableWidget_EC->setItem(i, 9, item);
            }
            break;
        }
        case Interface::FITKAbaMaterialBehaviorEnum::Lamina:
        {
            int rowNum = _elasticItem->getLaminaNumberOfRows();
            for (int i = 0; i < rowNum; i++) {
                QTableWidgetItem* item = new QTableWidgetItem(QString::number(_elasticItem->getLaminaE1(i)));
                _ui->tableWidget_Lamina->setItem(i, 0, item);
                item = new QTableWidgetItem(QString::number(_elasticItem->getLaminaE2(i)));
                _ui->tableWidget_Lamina->setItem(i, 1, item);
                item = new QTableWidgetItem(QString::number(_elasticItem->getLaminaNu12(i)));
                _ui->tableWidget_Lamina->setItem(i, 2, item);
                item = new QTableWidgetItem(QString::number(_elasticItem->getLaminaG12(i)));
                _ui->tableWidget_Lamina->setItem(i, 3, item);
                item = new QTableWidgetItem(QString::number(_elasticItem->getLaminaG13(i)));
                _ui->tableWidget_Lamina->setItem(i, 4, item);
                item = new QTableWidgetItem(QString::number(_elasticItem->getLaminaG23(i)));
                _ui->tableWidget_Lamina->setItem(i, 5, item);
                item = new QTableWidgetItem(QString::number(_elasticItem->getLaminaTemperature(i)));
                _ui->tableWidget_Lamina->setItem(i, 6, item);
            }
            break;
        }
        case Interface::FITKAbaMaterialBehaviorEnum::Orthotropics:
            break;
        case Interface::FITKAbaMaterialBehaviorEnum::AnIsotopic:
            break;
        case Interface::FITKAbaMaterialBehaviorEnum::Traction:
            break;
        case Interface::FITKAbaMaterialBehaviorEnum::CoupledTraction:
            break;
        case Interface::FITKAbaMaterialBehaviorEnum::Shear:
            break;
        }
    }

    void MaterialElasticWidget::saveValue(Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialElasticType type)
    {
        if (_elasticItem == nullptr)return;
        bool isTemp = _ui->checkBox_temp->isChecked();
        switch (type)
        {
        case Interface::FITKAbaMaterialBehaviorEnum::IsoTropic:
        {
            //强制失去焦点，否则获取数据有错误
            _ui->tableWidget_isotropic->setEnabled(false);
            //设置各项同性参数
            int rowNum = _ui->tableWidget_isotropic->rowCount();
            _elasticItem->setIsotropicNumberOfRows(rowNum);

            for (int i = 0; i < rowNum; i++){
                QTableWidgetItem* item = nullptr;
                double value = 0;

                item = _ui->tableWidget_isotropic->item(i, 0);
                if (!item)value = 0;
                else value = item->text().toDouble();
                _elasticItem->setIsotropicYoungsModulus(value);

                item = _ui->tableWidget_isotropic->item(i, 1);
                if (!item)value = 0;
                else value = item->text().toDouble();
                _elasticItem->setIsotropicPoissonRatio(value);

                if (isTemp) {
                    item = _ui->tableWidget_isotropic->item(i, 2);
                    if (!item)value = 0;
                    else value = item->text().toDouble();
                }
                else value = 0;
                _elasticItem->setIsotropicTemperature(value);
            }
            break;
        }
        case Interface::FITKAbaMaterialBehaviorEnum::EngineeringConstants:
        {
            //强制失去焦点，否则获取数据有错误
            _ui->tableWidget_EC->setEnabled(false);
            //工程常数参数设置
            int rowNum = _ui->tableWidget_EC->rowCount();
            _elasticItem->setEngineeringConstantsTemperature(rowNum);
            for (int i = 0; i < rowNum; i++) {
                QTableWidgetItem* item = nullptr;
                double value = 0;

                item = _ui->tableWidget_EC->item(i, 0);
                if (!item)value = 0;
                else value = item->text().toDouble();
                _elasticItem->setEngineeringConstantsE1(value);

                item = _ui->tableWidget_EC->item(i, 1);
                if (!item)value = 0;
                else value = item->text().toDouble();
                _elasticItem->setEngineeringConstantsE2(value);

                item = _ui->tableWidget_EC->item(i, 2);
                if (!item)value = 0;
                else value = item->text().toDouble();
                _elasticItem->setEngineeringConstantsE3(value);

                item = _ui->tableWidget_EC->item(i, 3);
                if (!item)value = 0;
                else value = item->text().toDouble();
                _elasticItem->setEngineeringConstantsNu12(value);

                item = _ui->tableWidget_EC->item(i, 4);
                if (!item)value = 0;
                else value = item->text().toDouble();
                _elasticItem->setEngineeringConstantsNu13(value);

                item = _ui->tableWidget_EC->item(i, 5);
                if (!item)value = 0;
                else value = item->text().toDouble();
                _elasticItem->setEngineeringConstantsNu23(value);

                item = _ui->tableWidget_EC->item(i, 6);
                if (!item)value = 0;
                else value = item->text().toDouble();
                _elasticItem->setEngineeringConstantsG12(value);

                item = _ui->tableWidget_EC->item(i, 7);
                if (!item)value = 0;
                else value = item->text().toDouble();
                _elasticItem->setEngineeringConstantsG13(value);

                item = _ui->tableWidget_EC->item(i, 8);
                if (!item)value = 0;
                else value = item->text().toDouble();
                _elasticItem->setEngineeringConstantsG23(value);

                if (isTemp) {
                    item = _ui->tableWidget_EC->item(i, 9);
                    if (!item)value = 0;
                    else value = item->text().toDouble();
                }
                else value = 0;
                _elasticItem->setEngineeringConstantsTemperature(value);
            }
            break;
        }
        case Interface::FITKAbaMaterialBehaviorEnum::Lamina:
        {
            //强制失去焦点，否则获取数据有错误
            _ui->tableWidget_Lamina->setEnabled(false);
            int rowNum = _ui->tableWidget_Lamina->rowCount();
            _elasticItem->setLaminaNumberOfRows(rowNum);
            for (int i = 0; i < rowNum; i++) {
                QTableWidgetItem* item = nullptr;
                double value = 0;

                item = _ui->tableWidget_Lamina->item(i, 0);
                if (!item)value = 0;
                else value = item->text().toDouble();
                _elasticItem->setLaminaE1(value);

                item = _ui->tableWidget_Lamina->item(i, 1);
                if (!item)value = 0;
                else value = item->text().toDouble();
                _elasticItem->setLaminaE2(value);

                item = _ui->tableWidget_Lamina->item(i, 2);
                if (!item)value = 0;
                else value = item->text().toDouble();
                _elasticItem->setLaminaNu12(value);

                item = _ui->tableWidget_Lamina->item(i, 3);
                if (!item)value = 0;
                else value = item->text().toDouble();
                _elasticItem->setLaminaG12(value);

                item = _ui->tableWidget_Lamina->item(i, 4);
                if (!item)value = 0;
                else value = item->text().toDouble();
                _elasticItem->setLaminaG13(value);

                item = _ui->tableWidget_Lamina->item(i, 5);
                if (!item)value = 0;
                else value = item->text().toDouble();
                _elasticItem->setLaminaG23(value);

                if (isTemp) {
                    item = _ui->tableWidget_Lamina->item(i, 6);
                    if (!item)value = 0;
                    else value = item->text().toDouble();
                }
                else value = 0;
                _elasticItem->setTemperature(value);
            }
            break;
        }
        case Interface::FITKAbaMaterialBehaviorEnum::Orthotropics:
            break;
        case Interface::FITKAbaMaterialBehaviorEnum::AnIsotopic:
            break;
        case Interface::FITKAbaMaterialBehaviorEnum::Traction:
            break;
        case Interface::FITKAbaMaterialBehaviorEnum::CoupledTraction:
            break;
        case Interface::FITKAbaMaterialBehaviorEnum::Shear:
            break;
        }
    }

    void MaterialElasticWidget::changeMaterialElasticType(Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialElasticType type)
    {
        //隐藏所有的TableWidget
        _ui->groupBox_isotropic->hide();
        _ui->groupBox_EC->hide();
        _ui->groupBox_Lamina->hide();

        //根据类型显示不同的TableWidget
        switch (type) {
        case Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialElasticType::IsoTropic:_ui->groupBox_isotropic->show(); break;
        case Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialElasticType::EngineeringConstants:_ui->groupBox_EC->show(); break;
        case Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialElasticType::Lamina:_ui->groupBox_Lamina->show(); break;
        case Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialElasticType::Orthotropics:break;
        case Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialElasticType::AnIsotopic:break;
        case Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialElasticType::Traction:break;
        case Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialElasticType::CoupledTraction:break;
        case Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialElasticType::Shear:break;
        }
    }

    void MaterialElasticWidget::changeMaterialTemp(Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialElasticType type, bool isTemp)
    {
        //隐藏温度列
        _ui->tableWidget_isotropic->hideColumn(2);
        _ui->tableWidget_EC->hideColumn(9);
        _ui->tableWidget_Lamina->hideColumn(6);

        if (isTemp == false)return;
        switch (type) {
        case Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialElasticType::IsoTropic:_ui->tableWidget_isotropic->showColumn(2); break;
        case Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialElasticType::EngineeringConstants:_ui->tableWidget_EC->showColumn(9); break;
        case Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialElasticType::Lamina:_ui->tableWidget_Lamina->showColumn(6); break;
        case Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialElasticType::Orthotropics:break;
        case Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialElasticType::AnIsotopic:break;
        case Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialElasticType::Traction:break;
        case Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialElasticType::CoupledTraction:break;
        case Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialElasticType::Shear:break;
        }
    }
}  // namespace GUI

